<?php
/**
 * FlickrPhotosetsProfile class file
 * @package FlickrPhotosets
 */

/**
 * This class handles the gathering and preparation of data for constructing
 * the profile box.
 * 
 * @package FlickrPhotosets
 * @author Brad Dougherty <bdougherty@gmail.com>
 * @version 7.10.18
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License 3.0
 * @since Class available since Release 2.0
 */
class FlickrPhotosetsProfile extends FlickrPhotosets {
	
	/**
	 * The size of the photo to render.
	 * @var string
	 */
	public $photo_size;
	
	/**
	 * The array of photos to show.
	 * @var array
	 */
	public $photos = array();
	
	/**
	 * Whether this is preview mode.
	 * @var boolean
	 */
	public $preview_mode;
	
	/**
	 * Contains strings for displaying the profile.
	 * @var array
	 */
	public $profile;
	
	/**
	 * The sort information.
	 * @var array
	 */
	public $sort = array();
	
	/**
	 * Gets the user's id, figures out whether to operate in preview mode,
	 * and initializes.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 */
	public function __construct() {
		parent::__construct();
		
		// Get the uid from the handle
		$this->uid = $_GET['handle'];
		
		// Set this to preview mode
		$this->preview_mode = (isset($_GET['preview'])) ? true : false;
		
		// Initialize
		$this->init_profile();
	}
	
	/**
	 * Gets the configuration from the post variables if operating in
	 * preview mode.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 */
	private function get_post_config() {
		if ($this->preview_mode) {
			$this->config['profile_display'] = $_REQUEST['profile_display'];
			$this->config['profile_count']   = $_REQUEST['profile_count'];
			$this->config['profile_tags']    = $_REQUEST['profile_tags'];
			$this->config['profile_tagmode'] = $_REQUEST['profile_tagmode'];
			$this->config['profile_sort']    = $_REQUEST['profile_sort'];
		}
	}
	
	/**
	 * Set strings that are related to the sort field.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 */
	private function get_sort_info() {
		if ($this->config['profile_sort'] == $this->profile_sort['date_posted_desc']) {
			$this->sort['param'] = 'date-posted-desc';
			$this->sort['string'] = 'last';
			$this->sort['type'] = 'posted';
		}
		else if ($this->config['profile_sort'] == $this->profile_sort['date_posted_asc']) {
			$this->sort['param'] = 'date-posted-asc';
			$this->sort['string'] = 'first';
			$this->sort['type'] = 'posted';
		}
		else if ($this->config['profile_sort'] == $this->profile_sort['date_taken_desc']) {
			$this->sort['param'] = 'date-taken-desc';
			$this->sort['string'] = 'last';
			$this->sort['type'] = 'taken';
		}
		else if ($this->config['profile_sort'] == $this->profile_sort['date_taken_asc']) {
			$this->sort['param'] = 'date-taken-asc';
			$this->sort['string'] = 'first';
			$this->sort['type'] = 'taken';
		}
		else if ($this->config['profile_sort'] == $this->profile_sort['interesting_desc']) {
			$this->sort['param'] = 'interestingness-desc';
			$this->sort['string'] = 'last';
			$this->sort['type'] = 'most interesting';
		}
		else if ($this->config['profile_sort'] == $this->profile_sort['interesting_asc']) {
			$this->sort['param'] = 'interestingness-asc';
			$this->sort['string'] = 'last';
			$this->sort['type'] = 'least interesting';
		}
	}
	
	/**
	 * Returns a string of the tags applied. Each tag links to the
	 * appropriate page on Flickr.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @return False if no tags are being used, the string otherwise
	 */
	private function get_tag_string() {
		if (!empty($this->config['profile_tags'])) {
			
			$split = explode(",", $this->config['profile_tags']);
			$tag_array = array();
			foreach ($split as $tag) {
				$tag = trim($tag);
				array_push($tag_array, '<a href="'.$this->flickr->urls_getUserPhotos($this->nsid).'tags/'.$tag.'/">'.$tag.'</a>');
			}
			
			$tag_string = (count($tag_array) > 1) ? 'with tags ' : 'with tag ';
			$tag_string .= implode(', ', $tag_array);
			
			return $tag_string;
			
		}
		else {
			return false;
		}
	}
	
	/**
	 * Gets the user's configuration information, initializes the Flickr
	 * object and runs the proper preparation method.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 */
	private function init_profile() {
		
		// Get the configuration
		$this->get_info();
		$this->get_post_config();
				
		// Initialize Flickr
		$this->init_flickr(false, true, false);
		$this->flickr_user = $this->flickr->people_getInfo($this->nsid);
		
		// Set the tag mode properly
		$this->config['profile_tagmode'] = ($this->config['profile_tagmode'] == $this->profile_tagmode['any']) ? 'any' : 'all';
		
		// Prepare the profile depending on the display
		if ($this->config['profile_display'] == $this->profile_display['sets'] or $this->config['profile_display'] == $this->profile_display['random_sets']) {
			$this->prepare_sets();
		}
		else if ($this->config['profile_display'] == $this->profile_display['overview']) {
			$this->prepare_overview();
		}
		else {
			$this->prepare_photos();
		}
		
		// Use a bigger size if there is only one photo.
		if (count($this->photos['photo']) == 1 and $this->config['profile_display'] != $this->profile_display['sets']) {
			$this->photo_size = 'small';
		}
		else {
			$this->photo_size = 'square';
		}
		
	}
	
	/**
	 * Prepares the information if displaying photos.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 */
	private function prepare_photos() {
		
		$this->get_sort_info();
		
		/*
		Showing most recent photos
		*/
		if ($this->config['profile_display'] == $this->profile_display['last']) {
			
			// Get the last 100 photos
			$page = 1;
			$this->photos = $this->flickr->photos_search(array(
				'user_id' => $this->nsid,
				'tags' => $this->config['profile_tags'],
				'tag_mode' => $this->config['profile_tagmode'],
				'sort' => $this->sort['param'],
				'page' => $page
			));
			
			// Remove photos that don't match the privacy settings
			$this->photos['photo'] = $this->remove_photos($this->photos['photo']);
			
			// If we don't find any eligible photos, keep getting the next 100 until we find enough
			$count = count($this->photos['photo']);
			while ($count < $this->config['profile_count']) {
				
				// Get the next page
				$page++;
				$photos = $this->flickr->photos_search(array(
					'user_id' => $this->nsid,
					'tags' => $this->config['profile_tags'],
					'tag_mode' => $this->config['profile_tagmode'],
					'sort' => $this->sort['param'],
					'page' => $page
				));
				$pages = $photos['pages'];
				$this->echo_debug('Getting page ', $page, ' of ', $pages);
				
				// Remove photos that don't match the privacy setting
				$photos['photo'] = $this->remove_photos($photos['photo']);
				
				// Add any eligible photos to the main array
				$this->photos['photo'] = array_merge($this->photos['photo'], $photos['photo']);
				
				// Recalculate the count
				$count = count($this->photos['photo']);
				$this->echo_debug('There are ', $count, ' photos eligible for display');
				
			}
			
			// If there are no photos, show an error
			if (count($this->photos['photo']) < 1) {
				$this->error(FlickrPhotosetsErrors::$profile_no_photos);
			}
			
			// Slice the photos down to however many they want to display
			$this->photos['photo'] = array_slice($this->photos['photo'], 0, $this->config['profile_count']);
			
			// Set the subtitle string
			if ($this->config['profile_sort'] == $this->profile_sort['interesting_desc'] or $this->config['profile_sort'] == $this->profile_sort['interesting_asc']) {
				$this->profile['subtitle'] = 'Showing the ';
				$this->profile['subtitle'] .= ($this->config['profile_count'] == 1) ? ' ' : $this->config['profile_count'].' ';
				$this->profile['subtitle'] .= $this->sort['type'].' ';
				$this->profile['subtitle'] .= (count($this->photos['photo']) == 1) ? 'photo' : 'photos';
			}
			else {
				$this->profile['subtitle'] = 'Showing the '.$this->sort['string'].' ';
				$this->profile['subtitle'] .= ($this->config['profile_count'] == 1) ? ' ' : $this->config['profile_count'].' ';
				$this->profile['subtitle'] .= (count($this->photos['photo']) == 1) ? 'photo' : 'photos';
				$this->profile['subtitle'] .= ' '.$this->sort['type'];
			}
			
			
		}
		/*
		Showing faily recent photos
		*/
		else if ($this->config['profile_display'] == $this->profile_display['recent']) {
			
			/*
			We need to set the sort to be descending so that we actually
			get recent photos!
			*/
			$reverse = false;
			if ($this->config['profile_sort'] == $this->profile_sort['date_posted_asc']) {
				$this->sort['param'] = 'date-posted-desc';
				$reverse = true;
			}
			else if ($this->config['profile_sort'] == $this->profile_sort['date_taken_asc']) {
				$this->sort['param'] = 'date-taken-desc';
				$reverse = true;
			}

			// Calculate the number of photos per page
			$photos_to_get = $this->config['profile_count'] * 15;
			$photos_to_get = ($photos_to_get > $this->flickr_user['photos']['count']) ? $this->flickr_user['photos']['count'] : $photos_to_get;

			// Retrieve the last $config['profile_count'] * 15 photos
			$photo_query = $this->flickr->photos_search(array(
				'user_id' => $this->nsid,
				'tags' => $this->config['profile_tags'],
				'tag_mode' => $this->config['profile_tagmode'],
				'sort' => $this->sort['param'],
				'per_page' => $photos_to_get,
			));
			
			// Remove photos that don't match the privacy settings
			$photo_query['photo'] = $this->remove_photos($photo_query['photo']);

			// If there are no photos, show an error
			if (count($photo_query['photo']) < 1) {
				$this->error(FlickrPhotosetsErrors::$profile_no_photos);
			}

			// Pick out the desired number of random photos
			//$photos_rand = array_rand($photo_query['photo'], $this->config['profile_count']);
			if (count($photo_query['photo']) > $this->config['profile_count']) {
				$photos_rand = array_rand($photo_query['photo'], $this->config['profile_count']);
			}
			else if (count($photo_query['photo']) == $this->config['profile_count']) {
				$photos_rand = $photo_query['photo'];
			}
			else {
				$this->error(FlickrPhotosetsErrors::$profile_no_photos);
			}
			
			// Create our photos['photo'] array
			if (count($photos_rand) > 1) {
				for ($i = 0; $i < count($photos_rand); $i++) {
					$this->photos['photo'][$i] = $photo_query['photo'][$photos_rand[$i]];
				}
			}
			else {
				$this->photos['photo'][0] = $photo_query['photo'][$photos_rand];
			}

			// Reverse the array if sorting ascending
			if ($reverse) {
				$this->photos['photo'] = array_reverse($this->photos['photo'], true);
			}
			
			// Set the subtitle string
			$this->profile['subtitle'] = 'Showing '.$this->config['profile_count'].' recent ';
			$this->profile['subtitle'] .= (count($this->photos['photo']) == 1) ? 'photo' : 'photos';
			$this->profile['subtitle'] .= ($this->sort['string'] == 'first') ? ', oldest first' : '';
			
		}
		/*
		Showing random photos
		*/
		else if ($this->config['profile_display'] == $this->profile_display['random']) {
			
			/*
			We need to set the sort to be descending so that we can get
			all of the user's photos
			*/
			$reverse = false;
			if ($this->config['profile_sort'] == $this->profile_sort['date_posted_asc']) {
				$this->sort['param'] = 'date-posted-desc';
				$reverse = true;
			}
			else if ($this->config['profile_sort'] == $this->profile_sort['date_taken_asc']) {
				$this->sort['param'] = 'date-taken-desc';
				$reverse = true;
			}
			
			// Calculate the number of photos per page
			$photos_to_get = 500;
			$photos_to_get = ($photos_to_get > $this->flickr_user['photos']['count']) ? $this->flickr_user['photos']['count'] : $photos_to_get;

			// Retrieve the last 500 photos
			$photo_query = $this->flickr->photos_search(array(
				'user_id' => $this->nsid,
				'tags' => $this->config['profile_tags'],
				'tag_mode' => $this->config['profile_tagmode'],
				'sort' => $this->sort['param'],
				'per_page' => $photos_to_get,
			));
			
			// If there are no photos, show an error
			if (count($photo_query['photo']) < 1) {
				$this->error(FlickrPhotosetsErrors::$profile_no_photos);
			}
			
			// Find out how many more pages we need to call and call them
			$pages_to_call = $photo_query['pages']-1;
			if ($pages_to_call > 0) {
				for ($i = 0; $i < $pages_to_call; $i++) {

					$additional_photos = $this->flickr->photos_search(array(
						'user_id' => $this->nsid,
						'tags' => $this->config['profile_tags'],
						'tag_mode' => $this->config['profile_tagmode'],
						'sort' => $this->sort['param'],
						'per_page' => $photos_to_get,
						'page' => ($i+2),
					));

					// Merge this array with the rest
					$photo_query['photo'] = array_merge($photo_query['photo'], $additional_photos['photo']);

				}
			}
			
			// Remove photos that don't match the privacy settings
			$photo_query['photo'] = $this->remove_photos($photo_query['photo']);
			
			// If there are no photos, show an error
			if (count($photo_query['photo']) < 1) {
				$this->error(FlickrPhotosetsErrors::$profile_no_photos);
			}
			
			// Pick out the desired number of random photos
			$photos_rand = array_rand($photo_query['photo'], $this->config['profile_count']);

			// Create our photos['photo'] array
			$photos_rand_count = count($photos_rand);
			if ($photos_rand_count > 1) {
				for ($i = 0; $i < $photos_rand_count; $i++) {
					$this->photos['photo'][$i] = $photo_query['photo'][$photos_rand[$i]];
				}
			}
			else {
				$this->photos['photo'][0] = $photo_query['photo'][$photos_rand];
			}
			
			// Reverse the array if sorting ascending
			if ($reverse) {
				$this->photos['photo'] = array_reverse($this->photos['photo'], true);
			}
			
			// Set the subtitle string
			$this->profile['subtitle'] = 'Showing '.$this->config['profile_count'].' random ';
			$this->profile['subtitle'] .= (count($this->photos['photo']) == 1) ? 'photo' : 'photos';
			$this->profile['subtitle'] .= ($this->sort['string'] == 'first') ? ', oldest first' : '';
			
		}
		
		// See all url
		$this->profile['see_all_url'] = $this->app_url.'/photos/'.$this->uid.'/';
		
		// Append tags to the subtitle string
		$this->profile['subtitle'] .= ' '.$this->get_tag_string();
		
	}
	
	/**
	 * Prepares the information if displaying an overview.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 */
	private function prepare_overview() {
		// Create display strings
		$this->profile['see_all_url'] = $this->app_url.'/photos/'.$this->uid.'/sets/';
		$this->profile['subtitle'] = $this->get_name(false, true, false).' Flickr Account';
	}
	
	/**
	 * Prepares the information if displaying sets.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 */
	private function prepare_sets() {
				
		// Get the user's sets
		$photosets = $this->flickr->photosets_getList($this->nsid);
		
		// If there are no photosets, show an error
		if (count($photosets['photoset']) < 1) {
			$this->error(FlickrPhotosetsErrors::$profile_no_photosets);
		}
		
		// Make sure the config count isn't greater than the number of sets
		if ($this->config['profile_count'] > count($photosets['photoset'])) {
			$this->config['profile_count'] = count($photosets['photoset']);
		}
		
		// Randomize
		if ($this->config['profile_display'] == $this->profile_display['random_sets']) {
			shuffle($photosets['photoset']);
		}
		
		/*
		Add the primary photos of each set to the photos array.
		Also include the set information.
		*/
		for ($i = 0; $i < $this->config['profile_count']; $i++) {
			$this->photos['photo'][$i] = $this->flickr->photos_getInfo($photosets['photoset'][$i]['primary']);
			$this->photos['photo'][$i]['set']['id'] = $photosets['photoset'][$i]['id'];
			$this->photos['photo'][$i]['set']['title'] = $photosets['photoset'][$i]['title'];
			$this->photos['photo'][$i]['set']['photos'] = $photosets['photoset'][$i]['photos'];
		}
		
		// Create display strings
		$this->profile['see_all_url'] = $this->app_url.'/photos/'.$this->uid.'/sets/';
		$this->profile['subtitle'] = 'Showing '.$this->config['profile_count'].' ';
		$this->profile['subtitle'] .= ($this->config['profile_display'] == $this->profile_display['random_sets']) ? 'random ' : '';
		$this->profile['subtitle'] .= (count($this->photos['photo']) == 1) ? 'set' : 'sets';
		
	}
	
}

?>